<html>
<head>
  <title>Evernote Export</title>
  <basefont face="Consolas" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="YXBJ Windows/602498 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
  <style>
    body, td {
      font-family: Consolas;
      font-size: 10pt;
    }
  </style>
</head>
<body>
<a name="3660"/>
<h1>gcc</h1>
<div>
<table bgcolor="#D4DDE5" border="0">
<tr><td><b>创建时间：</b></td><td><i>2020/12/16 13:42</i></td></tr>
<tr><td><b>更新时间：</b></td><td><i>2020/12/16 13:43</i></td></tr>
<tr><td><b>作者：</b></td><td><i>DaguguJ</i></td></tr>
<tr><td><b>标签：</b></td><td><i>C</i></td></tr>
</table>
</div>
<br/>

<div>
<span><div><div><br/></div><table style="border-collapse: collapse; min-width: 100%;"><colgroup><col style="width: 204px;"></col><col style="width: 950px;"></col></colgroup><tbody><tr><td style="border: 1px solid rgb(204, 204, 204); width: 204px; padding: 8px;"><div>gcc</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 950px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 204px; padding: 8px;"><div>常用编译命令选项（单文件）</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 950px; padding: 8px;"><div><br/></div><ul><li><div>假设源程序文件名为test.c。</div></li><li><div>1. 无选项编译链接</div></li><ul><li><div>用法：#gcc test.c</div></li><li><div>作用：将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件，默认输出为a.out。</div></li></ul><li><div>2. 选项 -o</div></li><ul><li><div>用法：#gcc test.c -o test</div></li><li><div>作用：将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。</div></li></ul><li><div>3. 选项 -E</div></li><ul><li><div>用法：#gcc -E test.c -o test.i</div></li><li><div>作用：将test.c预处理输出test.i文件。</div></li></ul><li><div>4. 选项 -S</div></li><ul><li><div>用法：#gcc -S test.i</div></li><li><div>作用：将预处理输出文件test.i汇编成test.s文件。</div></li></ul><li><div>5. 选项 -c</div></li><ul><li><div>用法：#gcc -c test.s</div></li><li><div>作用：将汇编输出文件test.s编译输出test.o文件。</div></li></ul><li><div>6. 无选项链接</div></li><ul><li><div>用法：#gcc test.o -o test</div></li><li><div>作用：将编译输出文件test.o链接成最终可执行文件test。</div></li></ul><li><div>7. 选项-O</div></li><ul><li><div>用法：#gcc -O1 test.c -o test</div></li><li><div>作用：使用编译优化级别1编译程序。级别为1~3，级别越大优化效果越好，但编译时间越长。</div></li></ul></ul></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 204px; padding: 8px;"><div>多源文件的编译方法</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 950px; padding: 8px;"><ul><li><div>如果有多个源文件，基本上有两种编译方法：</div></li><li><div>[假设有两个源文件为test.c和testfun.c]</div></li><ul><li><div>1. 多个文件一起编译</div></li><li><div>用法：#gcc testfun.c test.c -o test</div></li><li><div>作用：将testfun.c和test.c分别编译后链接成test可执行文件。</div></li></ul><li><div>2. 分别编译各个源文件，之后对编译后输出的目标文件链接。</div></li><ul><li><div>用法：</div></li><li><div>#gcc -c testfun.c //将testfun.c编译成testfun.o</div></li><li><div>#gcc -c test.c   //将test.c编译成test.o</div></li><li><div>#gcc -o testfun.o test.o -o test //将testfun.o和test.o链接成test</div></li></ul><li><div><br/></div></li><li><div>以上两种方法相比较，第一中方法编译时需要所有文件重新编译，而第二种方法可以只重新编译修改的文件，未修改的文件不用重新编译。</div></li></ul></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 204px; padding: 8px;"><div><span style="font-size: unset; color: unset; font-family: unset;">库文件连接</span></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 950px; padding: 8px;"><ul><li><div>开发软件时，完全不使用第三方函数库的情况是比较少见的，通常来讲都需要借助许多函数库的支持才能够完成相应的功能。从程序员的角度看，函数库实际上就是一些头文件（.h）和库文件（so、或lib、dll）的集合。</div></li><li><div>虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下，而库文件则放到/usr/lib/目录下；Windows所使用的库文件主要放在Visual Stido的目录下的include和lib，以及系统文件夹下。但也有的时候，我们要用的库不再这些目录下，所以GCC在编译时必须用自己的办法来查找所需要的头文件和库文件。</div></li><li><div>例如我们的程序test.c是在linux上使用c连接mysql，这个时候我们需要去mysql官网下载MySQL Connectors的C库，下载下来解压之后，有一个include文件夹，里面包含mysql connectors的头文件，还有一个lib文件夹，里面包含二进制so文件libmysqlclient.so</div></li><li><div>其中inclulde文件夹的路径是/usr/dev/mysql/include,lib文件夹是/usr/dev/mysql/lib</div></li><li><div><br/></div></li><li><div>3.1编译成可执行文件</div></li><ul><li><div>首先我们要进行编译test.c为目标文件，这个时候需要执行</div></li><li><div>gcc –c –I /usr/dev/mysql/include test.c –o test.o</div></li></ul><li><div>3.2链接</div></li><ul><li><div>最后我们把所有目标文件链接成可执行文件:</div></li><li><div>gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test</div></li><li><div><br/></div></li><li><div>Linux下的库文件分为两大类分别是动态链接库（通常以.so结尾）和静态链接库（通常以.a结尾），二者的区别仅在于程序执行时所需的代码是在运行时动态加载的，还是在编译时静态加载的。</div></li></ul><li><div>3.3强制链接时使用静态链接库</div></li><ul><li><div>默认情况下， GCC在链接时优先使用动态链接库，只有当动态链接库不存在时才考虑使用静态链接库，如果需要的话可以在编译时加上-static选项，强制使用静态链接库。</div></li><li><div>在/usr/dev/mysql/lib目录下有链接时所需要的库文件libmysqlclient.so和libmysqlclient.a，为了让GCC在链接时只用到静态链接库，可以使用下面的命令:</div></li><li><div>gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test</div></li></ul><li><div>静态库链接时搜索路径顺序：</div></li><ul><li><div>1. ld会去找GCC命令中的参数-L</div></li><li><div>2. 再找gcc的环境变量LIBRARY_PATH</div></li><li><div>3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的</div></li></ul><li><div>动态链接时、执行时搜索路径顺序:</div></li><ul><li><div>1. 编译目标代码时指定的动态库搜索路径</div></li><li><div>2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径</div></li><li><div>3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径</div></li><li><div>4. 默认的动态库搜索路径/lib</div></li><li><div>5. 默认的动态库搜索路径/usr/lib</div></li></ul><li><div>有关环境变量：</div></li><ul><li><div>LIBRARY_PATH环境变量：指定程序静态链接库文件搜索路径</div></li><li><div>LD_LIBRARY_PATH环境变量：指定程序动态链接库文件搜索路径</div></li></ul></ul></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 204px; padding: 8px;"><div><br/></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 950px; padding: 8px;"><div><br/></div></td></tr></tbody></table><div><br/></div></div><div><br/></div></span>
</div></body></html> 